#include "js_editor_extension.hpp"
#include <duktape.h>
#include "data/editor_data.hpp"
#include "scripting/scripting_api.h"
#include "scripting/scripting_module.h"
#include "utils/log.hpp"

#include <dukglue.h>

JsEditorExtension::JsEditorExtension(EditorTarget type, std::string title, const std::string &script_path): IEditorScript(type, std::move(title), script_path, g_current_module)
{
    
}

JsEditorExtension::~JsEditorExtension()
{
    
}

void JsEditorExtension::execute(const void *arg)
{
    if (duk_get_global_string(ctx_, "main"))
    {
        auto main_func = DukValue::take_from_stack(ctx_);
        switch (apply_target_) {
        case IEditorScript::eItem: dukglue_call(ctx_, main_func, (ItemNode*)arg); break;
        case IEditorScript::eDay:  dukglue_call(ctx_, main_func, (DayLevelNode*)arg); break;
        case IEditorScript::eMonth:dukglue_call(ctx_, main_func, (MonthLevelNode*)arg); break;
        case IEditorScript::eYear: dukglue_call(ctx_, main_func, (YearLevelNode*)arg); break;
        case IEditorScript::eCount: break;
        }
        duk_pop(ctx_);
    }
}

IScript* JsEditorExtension::create(EditorTarget target, std::string title, const std::string_view &code, const std::string &script_path)
{
    auto ext = new JsEditorExtension(target, std::move(title), script_path);
    if (!ext->compile(code))
    {
        delete ext;
        ext = nullptr;
    }
    return ext;
}

bool JsEditorExtension::compile(const std::string_view& code) const
{
    bool ok = false;
    auto rc = duk_peval_lstring_noresult(ctx_, code.data(), code.length());
    if (rc == DUK_EXEC_SUCCESS)
    {
        if (duk_get_global_string(ctx_, "main"))
        {
            ok = duk_is_function(ctx_, -1);
            if (!ok) {
                L_ERROR("main is not a function!!");
            }
            duk_pop(ctx_);
        }
    }
    return ok;
}
